package com.kevin.core;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;

import org.dom4j.Document;
import org.dom4j.Element;

import com.kevin.bean.Project;
import com.kevin.util.ConfigUtil;
import com.kevin.util.FileUtils;
import com.kevin.util.XMLUtils;


public class Builder {
	
	final static String file_separator=System.getProperty("file.separator");
	final static String line_separator=System.getProperty("line.separator");
	
    Logger logger=Logger.getAnonymousLogger();
	
	private Project project;
	
	private List<String> sourceFilePathList;
	
	private String diskChar;
	
	public Builder(Project config) {
		super();
		this.project = config;
		this.sourceFilePathList= getSourceFilePathList();
		this.diskChar=getDiskChar();
	}


	public void build(){
		
		copy();
		
		if(!project.isNewProject()){
			appendServiceAgent();
		}
		
		clean();
	}
	
	
	/**
	 * 复制和替换
	 */
	private void copy(){
		Map<String, String> map = project.getConFilter();
		Map<String, String> filePathMap = getFilePathMap();
		System.out.println("filePathMap:\n"+filePathMap);
		Set<Entry<String, String>> entrySet = filePathMap.entrySet();
		for(Entry<String, String> entry:entrySet ){
//			System.out.println(" src:"+entry.getKey());
//			System.out.println("dist:"+entry.getValue()+"\n");
			FileUtils.replaceContent(entry.getKey(), entry.getValue(), map); 
		}
	}
	
	/**
	 * 获取替换过的目标路径
	 * @param targetPath
	 * @param sourceFilePathList
	 * @return
	 */
	private Map<String,String> getFilePathMap(){
		Map<String, String> map = project.getConFilter();
		Map<String,String> filePathMap =new HashMap<String,String>();
		String messageXsdVersion = project.getMessageXsdVersion();
		String version = "_Message" + messageXsdVersion;
		for(String s:sourceFilePathList){
			if(s.indexOf("PortTypeEndpointHTTP.xml")>-1&&project.isNewProject){
				continue;
			}
			if(s.indexOf("PortTypeEndpointJMS.xml")>-1&&project.isNewProject){
				continue;
			}
			
			// message version process
			if(s.indexOf("_Message")>-1&&s.indexOf(version)==-1){
				continue;
			}
			// message version process
			if(s.indexOf(".serviceagent")>-1&&!project.isNewProject()){
				continue;
			}
			// req-res provider process
			if(s.indexOf("RqTransform")>-1){
				if(project.isHasProvider()&&s.indexOf("RqTransform2")>-1){
					continue;
				}else if(!project.isHasProvider()&&s.indexOf("RqTransform1")>-1){
					continue;
				}
			}
			if(s.indexOf("RsTransform")>-1){
				if(project.isHasProvider()&&s.indexOf("RsTransform2")>-1){
					continue;
				}else if(!project.isHasProvider()&&s.indexOf("RsTransform1")>-1){
					continue;
				}
			}
			
			///// targetPath process
			String targetPath = FileUtils.replace(s, map);
			// targetPath=targetPath.replace(diskChar,project.getTargetDir());
			int pos = targetPath.indexOf("ESBPrj1.0.0");
			targetPath = project.getWorkspace() + targetPath.substring(pos);
			
			if(s.indexOf("_Message")>-1){
				targetPath = targetPath.replace(version, "");
			}
			
			// req-res provider process
			if(s.indexOf("RqTransform")>-1){
				targetPath = targetPath.replace("RqTransform1", "RqTransform");
				targetPath = targetPath.replace("RqTransform2", "RqTransform");
			}
			if(s.indexOf("RsTransform")>-1){
				targetPath = targetPath.replace("RsTransform1", "RsTransform");
				targetPath = targetPath.replace("RsTransform2", "RsTransform");
			}
			filePathMap.put(s, targetPath);
		}
		return filePathMap;
	}
	
	
	
	
	/**
	 * 获取原始模板路径列表
	 * @param template
	 * @return
	 */
	private List<String> getSourceFilePathList(){
		if(project.projectType!=null){
			String templateDir = System.getProperty("user.dir")+file_separator+"template"+file_separator+project.projectType;
			List<String> filePathList=new ArrayList<String>();
			FileUtils.getFilePathList(filePathList, templateDir);
			return filePathList;
		}
		return Collections.emptyList();
	}
	
	private String getDiskChar() {
		URL resource = Builder.class.getClassLoader().getResource(".");
		String path = resource.getPath();
		return path.substring(0, path.indexOf(":")+1);
	}
	
	private void appendServiceAgent() {
		try {
		    String serverAgentPath=project.workspace+"/ESBPrj1.0.0/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/"+project.getServiceName()+".serviceagent";
		    Document doc = XMLUtils.parse(serverAgentPath);
		    String xpath="/serviceResource/config/interfaceImpl/tab/config/detail/tab/config/operations";
		    Element operations = (Element) doc.selectSingleNode(xpath);
		    Element e = operations.addElement("row");
		    e.addAttribute("opName", project.getOperationName());
		    e.addAttribute("opImpl", "/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/PortType"+project.getOperationName()+".process");
		    
		    String endpointHTTPFilePath=project.workspace+"/ESBPrj1.0.0/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/PortTypeEndpointHTTP.xml";
		    String endpointHTTPXmlPath="serviceResource/config/interfaceImpl/tab/config/detail/tab/config/epBindings/row[1]/config/epDetail/tab/config/soap";
		    
		    String endpointJMSFilePath=project.workspace+"/ESBPrj1.0.0/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/PortTypeEndpointJMS.xml";
		    String endpointJMSXmlPath="serviceResource/config/interfaceImpl/tab/config/detail/tab/config/epBindings/row[2]/config/epDetail/tab/config/soap/operation";
		    
		    Element endpointHTTPElement = XMLUtils.parse(endpointHTTPFilePath).getRootElement();
		    Element httpSrc = (Element) doc.selectSingleNode(endpointHTTPXmlPath);
		    httpSrc.add(endpointHTTPElement);
		    
		    Element endpointJMSElement = XMLUtils.parse(endpointJMSFilePath).getRootElement();
		    Element jmsSrc = (Element) doc.selectSingleNode(endpointJMSXmlPath);
		    jmsSrc.add(endpointJMSElement);
		    
//		    XMLUtils.printDocument(doc);
		    XMLUtils.saveDocument(doc,serverAgentPath);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
   private void clean(){
	   String endpointHTTPFilePath=project.workspace+"/ESBPrj1.0.0/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/PortTypeEndpointHTTP.xml";
	    
	    String endpointJMSFilePath=project.workspace+"/ESBPrj1.0.0/CoreServices/BusinessServices/"+project.getServiceName()+"/v1.0.0/PortTypeEndpointJMS.xml";
	    
	   File endpointHTTPFile=new File(endpointHTTPFilePath);
	    File endpointJMSFile=new File(endpointJMSFilePath);
	    if(endpointHTTPFile.exists()){
	    	endpointHTTPFile.delete();
	    }
	    if(endpointJMSFile.exists()){
	    	endpointJMSFile.delete();
	    }
   }
	
	
	
	public static void main(String[] args) {
//		Project mock_osx_new_project = Project.mock_osx_pub_sub_new_project();
//		Builder builder = new Builder(mock_osx_new_project);
//		builder.build();
//		
//		Project mock_osx_append_project = Project.mock_osx_pub_sub_append_project();
//		Builder builder2 = new Builder(mock_osx_append_project);
//		builder2.build();
		
//		Project mock_osx_req_res_new_project = Project.mock_osx_req_res_new_project();
//		Builder builder3 = new Builder(mock_osx_req_res_new_project);
//		builder3.build();
		
//		Project mock_osx_req_res_append_project = Project.mock_osx_req_res_append_project();
//		Builder builder4 = new Builder(mock_osx_req_res_append_project);
//		builder4.build();
		
		
		Project mock_osx_req_res_append_project = Project.mock_osx_req_res_append_project();
		Builder builder4 = new Builder(mock_osx_req_res_append_project);
		builder4.build();
		
		System.out.println(ConfigUtil.get("workspace","test"));
		
	}
}
